﻿//使用cookie时的一个工具类（面向对象，原型）
 //构造函数：用指定的名字和可选的性质为指定的文档创建一个cookie对象。
 //参数：
 //document:保存cookie的Document对象，必须的。
 //name:指定cookie名的字符串。必须的。
 //hours:一个可选的数字，指定从现在起到过期时间的小时数
 //path:一个可选的字符串，指定了cookie的路径性质
 //domain:一个可选的字符串，指定了cookie的域性质
 //secure:一个可选的布尔值，为true ，需要一个安全的cookie

 function Cookie(document, name, hours, path, domain, secure)
{
    // 该对象的所有预定义的属性都以'$'开头。
    // 这是为了与存储在cookie中的属性值区分开。
    this.$document = document;
    this.$name = name;
    if (hours)  //当字符串为空时，为false, 不为空时，为true
        this.$expiration = new Date((new Date()).getTime() + hours*3600000);
    else this.$expiration = null;
    if (path) this.$path = path; else this.$path = null;
    if (domain) this.$domain = domain; else this.$domain = null;
    if (secure) this.$secure = true; else this.$secure = false;
}

// 该函数是cookie对象的 store() 方法。
Cookie.prototype.store = function () {
    // 首先，遍历cookie对象的属性，并且将cookie值连接起来。
    // 由于cookie将等号和分号作为分隔符。
    // 所以我们使用冒号和&来分隔存储在单个cookie值中的状态变量。
    // 注意：我们对每个状态变量的值进行了转义，以防它含有标点符号或其它非法字符。
    var cookieval = "";
    for(var prop in this) {
        // 忽略所有名字以$开头的属性和所有方法（typeof的用法）
        if ((prop.charAt(0) == '$') || ((typeof this[prop]) == 'function'))
            continue;
        if (cookieval != "") cookieval += '&';
        cookieval += prop + ':' + escape(this[prop]);
    }

    // 既然我们已经有了cookie只，就可以连接完成的cookie串。
 //其中包括名字和创建cookie对象时指定的各种性质.
    var cookie = this.$name + '=' + cookieval;
    if (this.$expiration)
        cookie += '; expires=' + this.$expiration.toGMTString();
    if (this.$path) cookie += '; path=' + this.$path;
    if (this.$domain) cookie += '; domain=' + this.$domain;
    if (this.$secure) cookie += '; secure';

    // 下面设置Document.cookie属性来保存cookie 
    this.$document.cookie = cookie;
}


// 该函数是cookie对象的load()方法
Cookie.prototype.load = function() {
    // 首先得到属于该文档的所有cookie的列表,
    // 通过读Document.cookie属性可以实现这一点.
    var allcookies = this.$document.cookie;
    if (allcookies == "") return false;

    // 下面从该列表中提取已命名的cookie.
    var start = allcookies.indexOf(this.$name + '=');
    if (start == -1) return false;   // 该页未定义cookie
    start += this.$name.length + 1;  // 跳过名字和等号.
    var end = allcookies.indexOf(';', start);
    if (end == -1) end = allcookies.length;
    var cookieval = allcookies.substring(start, end);

    // 既然我们已经提取出了已命名的cookie 的值,就可以把它分割存储到状态变量名和值.
 // 名字/值对由&分隔,名字和值之间则由冒号分隔.
 //我们使用split()方法解析所有数据.
    var a = cookieval.split('&');//a 表示一个数组了    // 分隔成名字/值对.
    for(var i=0; i < a.length; i++)  // 把每对值存入数组.
        a[i] = a[i].split(':'); //a表示二维数组

    // 既然我们已经解析了cookie值
    // 就可以设置cookie对象中的状态变量的名字和值.
    // 注意我们对属性值调用了unescape(),因为存储它们时调用了escape()方法.
    for(var i = 0; i < a.length; i++) {
        this[a[i][0]] = unescape(a[i][1]);  //a[][]参数从0开始.
    }

    // 返回成功
    return true;
}

// 该函数是cookie对象的remove() 方法.
Cookie.prototype.remove = function() {
    var cookie;
    cookie = this.$name + '=';
    if (this.$path) cookie += '; path=' + this.$path;
    if (this.$domain) cookie += '; domain=' + this.$domain;
    cookie += '; expires=Fri, 02-Jan-1970 00:00:00 GMT';

    this.$document.cookie = cookie;  //原来的被覆盖了.
}